home *** CD-ROM | disk | FTP | other *** search
-
- Notes on the GLU polygon tesselation facility implemented by Bogdan Sikorski...
-
-
-
- The tesselation module is provided under the same terms as the Mesa
- package.
-
- This is the first release of polygon tesselation code for Mesa.
- It was written during my very little free time, so lets name it:
- "its not perfect". If someone hates pointers, don't look at the code.
- I preffer dynamic allocation versus static. But _all_ ideas, suggestions,
- bug reports and fixes are welcome (if You want, also flames). I am aware
- that many things could have been written using better techniques, but time
- that I could devote to this library was very limited. It is not well commented,
- excuse me. Also I am thinking of continuing working on this code to improve,
- fix and polish it. And make it as compliant as possible to the OpenGL, so
- software ports from OpenGL to Mesa will work correctly. If You know of any
- differences in behaviour, expected input/output between Mesa tesselation library
- and OpenGL, please send me a note. I explain later on why I am not
- confident with this code.
-
- I tried to be fully compliant with the OpenGL routines. By "tried" I mean that
- up to my knowledge it behaves as OpenGL tesselation routines. Just recently
- I began to experiment with OpenGL (actually only Mesa), and also have
- no access to any machine providing official implementation of OpenGL,
- nor access to books (particulary Addison-Wesley publications). Thus my
- knowledge on how the original tesselation code works, what kind of data
- it expects etc. is based _only_ on the publicly available documentation
- provided by SGI. Namely:
-
- * "The OpenGL Graphics System Utility Library" by K.P.Smith
- (Silicon Graphics, 1992)
- * "The OpenGL Graphics Interface" by M.Segal and K.Akeley
- (Silicon Graphics, 19??)
- * "OpenGL and X, Part 1: Introduction" by M.J.Kilgard
- (Silicon Graphics, 1994)
- * "OpenGL and X, Part 2: Using OpenGL with Xlib" by M.J.Kilgard
- (Silicon Graphics, 1994)
- * "OpenGL Graphics with the X Window System" by P.Karlton
- (Silicon Graphics, 1993)
- * Online Docs - Appendix C of OpenGL Programming Guide, Polygon Tesselation
- (partial text cut and sent by e-mail)
-
-
- The tesselation routines use slightly different prototypes than the ones
- specified in the mentioned above publications. The _only_ differences are
- the enumeration types which are not GLenum, but are GLUenum. So the
- implemented routines have following prototypes:
-
- GLUtringulatorObj *gluNewTess(void);
-
- void gluTessCallback(GLUtriangulatorObj *,GLUenum,void (*)());
- ^^^^^^^
- void gluBeginPolygon(GLUtriangulatorObj *);
-
- void gluTessVertex(GLUtriangulatorObj *,GLdouble [3],void *);
-
- void gluNextContour(GLUtriangulatorObj *,GLUenum);
- ^^^^^^^
- void gluEndPolygon(GLUtriangulatorObj *);
-
- const GLubyte *gluErrorString(GLUenum);
- ^^^^^^^
- prototypes for callback functions:
-
- void <begin>(GLUenum);
- ^^^^^^^
- void <edgeFlag>(GLboolean);
- void <vertex>(void *);
- void <end>(void);
- void <error>(GLUenum);
- ^^^^^^^
-
- The begin callback will be called only with GLU_TRIANGLES. No support
- for traingle fans or strips yet.
-
- In case of errors an internal error variable is set to the appropiate
- error enum values (GLU_TESS_ERROR?). Initially it is set to GLU_NO_ERROR.
- The OpenGL library provides 8 error conditions, the tesselation code
- of Mesa provides 9. They are:
-
- GLU_TESS_ERROR1: missing gluEndPolygon /* same as OpenGL */
- GLU_TESS_ERROR2: missing gluBeginPolygon /* same as OpenGL */
- GLU_TESS_ERROR3: misoriented contour /* not used in Mesa
- in OpenGL is bad orientation or intersecting edges */
- GLU_TESS_ERROR4: vertex/edge intersection /* same as OpenGL */
- GLU_TESS_ERROR5: misoriented or self-intersecting loops /* same as OpenGL */
- GLU_TESS_ERROR6: coincident vertices /* same as OpenGL */
- GLU_TESS_ERROR7: colinear vertices /* OpenGL's illegal data */
- GLU_TESS_ERROR8: intersecting edges /* same as OpenGL */
- GLU_TESS_ERROR9: not coplanar contours /* new for Mesa */
-
- The Mesa tesselation code ignores all data and calls after detecting an error
- codition. This means that a _new_ tesselation object must be used for further
- triangulations. Maybe this is too restrictive, and will be lifted in
- future versions.
-
- The tesselation code completely ignores the type parameter passed in
- gluNextContour. It also doesn't check if the passed parameter is a legal
- enum value - ignores silently (maybe at least this should be checked).
- The reason I chose this behaviour is based on what I read in the
- beforementioned documents. I cite:
-
- "....
- void gluNextContour(GLUtriangulatorObj *tessobj, GLenum type);
-
- Marks the beginning of the next contour when multiple contours make up the
- boundary of the polygon to be tessellated. type can be GLU_EXTERIOR,
- GLU_INTERIOR, GLU_CCW, GLU_CW, or GLU_UNKNOWN. These serve only as
- to the tessellation. If you get them right, the tessellation might
- go faster. If you get them wrong, they're ignored, and the tesselation still
- works.
- ....."
-
- I hope You agree with me that my decision was correct. Mesa tesselation
- _always_ checks by itself the interrelations between contours. Just as if
- all contours were specified with the type GLU_UNKNOWN.
-
- One of OpenGL's policy is not to check all error conditions - rely sometimes
- that the user "got things right". This is justified, since exhausting
- error checking is timeconsuming, and would significantly slow down
- a correct application. The Mesa tesselation code assumes only _one_ condition
- when triangulating - all vertices in a contour are planar. This is _not_
- checked for correctness. Trying to tesselate such objects will lead to
- unpredictable output.
-
- And now we arrive to the moment where I would like to list the required
- (but checked for) conditions for triangulation, as well as summarize the
- library:
-
- * all contours in a single tesselation cycle _must_ be coplanar - if not
- an error is raised (and if provided a call to the error callback
- is made)
- * the contours can be passed in _any_ order, exteriors and holes can be
- intermixed within a tesselation cycle and the correct hierarchy
- will be determined by the library; thus specifying first holes then
- exteriors, then holes within holes form a valid input.
- * a hole within a hole is consider to be a yet another exterior contour
- * multiple exterior contours (polygons) can be tesselated in one cycle;
- _but_ this significantly degrades performance since many tests will be
- performed for every contour pair; if You want triangulation to be fast
- tesselate a single polygon (with possible holes) one at a time.
- * orientation of exterior contours is arbitray, but if it has holes,
- all interior holes of this particular exterior contour _must_ have an
- opposite orientation.
- * the output triangles have the same orientation as the exterior contour
- that forms them
- * each triangle is "enclosed" within the begin and end callbacks;
- this is not efficent, but was made on purpose; so if triangulation
- results in 2 triangles the following callbacks will be made in such
- order:
- <begin>(GLU_TRAINGLES)
- <vertex>(...) /* 3 vertices of first triangle */
- <vertex>(...)
- <vertex>(...)
- <end>()
- <begin>(GLU_TRAINGLES)
- <vertex>(...) /* 3 vertices of second triangle */
- <vertex>(...)
- <vertex>(...)
- <end>()
- Of course only when begin, vertex, and end callback were provided,
- otherwise no output is done (actually tesselation does not take place).
- * You will notice that some output traingles are very "thin"; there
- exist possible several ways to traingulate a polygon, but "smart" code
- avoiding such cases would require time to write, and will impact on
- execution speed.
- * like OpenGL, no new vertices are introduced during triangulation
- * if the edgeflag callback is provided it will be called whenever
- the just-about-to be output vertex begins a different type of edge
- than the previous vertices; always before the first output a call
- is made with GL_TRUE, to allow synchronization.
- * all intermediate computations are done using GLdouble type, and comparisons
- are biased with a precision value (EPSILON defined in tess.h)
- * the point_in_poly function is my adaptation of code from the
- comp.graphics.alg newsgroup FAQ (originally written by Mr. Wm. Randolph
- Franklin, modified by Scott Anguish).
- * the edge_edge_intersect test is also an adopted code from comp.graphics.alg
- newsgroup FAQ
- * the general idea for traingulation used in this library is described in
- the book "Computational Geometry in C" by Joseph O'Rourke.
-
-
- Excuse my English, its not my mother tongue. I should be available for some
- time uner the following e-mail address. But For how long I am not certain.
- Once I am settled in my new place, I'll post on the Mesa mailing list
- my new address.
-
- (PS: today is my last day of work here, I'm changing my job).
-
- Bogdan. ( bogdan@dia.unisa.it )
-
- Apr 28, 1995.
-
-